package com.matrix.order.interfaces.controller;

import com.matrix.api.order.dto.AddDishDTO;
import com.matrix.api.order.dto.CancelDishDTO;
import com.matrix.api.order.dto.CreateOrderDTO;
import com.matrix.api.order.dto.OrderRejectDTO;
import com.matrix.api.order.vo.*;
import com.matrix.common.aspect.Idempotent;
import com.matrix.common.domain.PageResult;
import com.matrix.common.domain.Result;
import com.matrix.common.enums.UserTypeEnum;
import com.matrix.order.application.OrderAppService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
/**
 * @author 有点甜
 * @since 2025/7/27
 */
@Slf4j
@RestController
@RequiredArgsConstructor
public class OrderController {

    private final OrderAppService orderAppService;

    @PostMapping("/app/order/create")
    @PreAuthorize("hasAuthority('USER')")
    @Idempotent(message = "订单正在处理中,请勿重复提交")
    public Result<AsyncOrderResultVO> createOrderAsync(@RequestHeader("X-User-ID") Long userId,
                                                       @Valid @RequestBody CreateOrderDTO orderDTO) {
        AsyncOrderResultVO result = orderAppService.createOrderAsync(userId, orderDTO);
        return Result.success(result);
    }

    @PostMapping("/app/order/finish-meal/{orderId}")
    @PreAuthorize("hasAuthority('USER')")
    public Result<Void> finishMeal(@RequestHeader("X-User-ID") Long userId,
                                   @PathVariable("orderId") Long orderId) {
        orderAppService.finishMeal(userId, orderId);
        return Result.success();
    }

    @PostMapping("/app/order/add-dish/{orderId}")
    @PreAuthorize("hasAuthority('USER')")
    public Result<AddDishResultVO> addDish(@RequestHeader("X-User-ID") Long userId,
                                           @PathVariable("orderId") Long orderId,
                                           @Valid @RequestBody AddDishDTO addDishDTO) {
        return Result.success(orderAppService.addDish(userId, orderId, addDishDTO));
    }

    @PostMapping("/app/order/cancel-dish/{orderId}")
    @PreAuthorize("hasAuthority('USER')")
    public Result<Void> cancelDish(@RequestHeader("X-User-ID") Long userId,
                                   @PathVariable("orderId") Long orderId,
                                   @Valid @RequestBody CancelDishDTO cancelDishDTO) {
        orderAppService.requestCancelDish(userId, orderId, cancelDishDTO);
        return Result.success();
    }

    @PostMapping("/app/order/call-waiter/{orderId}")
    @PreAuthorize("hasAuthority('USER')")
    public Result<Void> callWaiter(@RequestHeader("X-User-ID") Long userId,
                                   @PathVariable("orderId") Long orderId) {
        orderAppService.callWaiter(userId, orderId);
        return Result.success();
    }

    @GetMapping("/app/orders")
    @PreAuthorize("hasAuthority('USER')")
    public Result<PageResult<OrderBriefVO>> getUserOrders(
            @RequestHeader("X-User-ID") Long userId,
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize,
            @RequestParam(required = false) String statusGroup) {
        return Result.success(orderAppService.getUserOrders(userId, pageNum, pageSize, statusGroup));
    }


    @GetMapping("/merchant/orders")
    @PreAuthorize("hasAuthority('MERCHANT')")
    public Result<PageResult<OrderBriefVO>> getOrderListForMerchant(
            @RequestHeader("X-User-ID") Long userId,
            @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
            @RequestParam(value = "pageSize", defaultValue = "10") int pageSize,
            @RequestParam(value = "status", required = false) Integer status) {
        return Result.success(orderAppService.getOrderListForMerchant(userId, pageNum, pageSize, status));
    }

    @GetMapping("/merchant/order/{orderId}")
    @PreAuthorize("hasAuthority('MERCHANT')")
    public Result<OrderDetailVO> getOrderDetailForMerchant(
            @RequestHeader("X-User-ID") Long userId,
            @PathVariable("orderId") Long orderId) {
        return Result.success(orderAppService.getOrderDetail(orderId, userId, UserTypeEnum.MERCHANT));
    }

    @PostMapping("/merchant/order/accept/{orderId}")
    @PreAuthorize("hasAuthority('MERCHANT')")
    public Result<Void> acceptOrder(@RequestHeader("X-User-ID") Long userId,
                                    @PathVariable("orderId") Long orderId) {
        orderAppService.acceptOrder(userId, orderId);
        return Result.success();
    }

    @PostMapping("/merchant/order/reject/{orderId}")
    @PreAuthorize("hasAuthority('MERCHANT')")
    public Result<Void> rejectOrder(@RequestHeader("X-User-ID") Long userId,
                                    @PathVariable("orderId") Long orderId,
                                    @RequestBody @Valid OrderRejectDTO rejectDTO) {
        orderAppService.rejectOrder(userId, orderId, rejectDTO.getReason());
        return Result.success();
    }

    @PostMapping("/merchant/order/finish-production/{orderId}")
    @PreAuthorize("hasAuthority('MERCHANT')")
    public Result<Void> finishProduction(@RequestHeader("X-User-ID") Long userId,
                                         @PathVariable("orderId") Long orderId) {
        orderAppService.finishProduction(userId, orderId);
        return Result.success();
    }

    @PostMapping("/merchant/order/serving/{orderId}")
    @PreAuthorize("hasAuthority('MERCHANT')")
    public Result<Void> startServing(@RequestHeader("X-User-ID") Long userId,
                                     @PathVariable("orderId") Long orderId) {
        orderAppService.startServing(userId, orderId);
        return Result.success();
    }

    @PostMapping("/merchant/order/served/{orderId}")
    @PreAuthorize("hasAuthority('MERCHANT')")
    public Result<Void> finishServing(@RequestHeader("X-User-ID") Long userId,
                                      @PathVariable("orderId") Long orderId) {
        orderAppService.finishServing(userId, orderId);
        return Result.success();
    }

    @PostMapping("/merchant/order/approve-cancel-dish/{orderItemId}")
    @PreAuthorize("hasAuthority('MERCHANT')")
    public Result<Void> approveCancelDish(@RequestHeader("X-User-ID") Long userId,
                                          @PathVariable("orderItemId") Long orderItemId) {
        orderAppService.approveCancelDish(userId, orderItemId);
        return Result.success();
    }

    @PostMapping("/merchant/order/reject-cancel-dish/{orderItemId}")
    @PreAuthorize("hasAuthority('MERCHANT')")
    public Result<Void> rejectCancelDish(@RequestHeader("X-User-ID") Long userId,
                                         @PathVariable("orderItemId") Long orderItemId) {
        orderAppService.rejectCancelDish(userId, orderItemId);
        return Result.success();
    }

    @GetMapping("/app/order/{orderId}")
    @PreAuthorize("hasAuthority('USER')")
    public Result<OrderDetailVO> getOrderDetailForUser(
            @RequestHeader("X-User-ID") Long userId,
            @PathVariable("orderId") Long orderId) {
        return Result.success(orderAppService.getOrderDetail(orderId, userId, UserTypeEnum.USER));
    }
}